// SPDX-License-Identifier: Mulan PSL v2
/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * This software is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 *
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

use std::{
    error::Error as StdError,
    ops::{Deref, DerefMut},
};

/// A guard providing read access to received data with zero-copy semantics.
///
/// This trait enables efficient data processing by allowing direct access to
/// the underlying byte buffer while ensuring safe lifetime management.
pub trait ReadGuard<'a>: Deref<Target = [u8]> {
    /// Advances the read position in the data stream.
    ///
    /// # Parameters
    /// - `data_len`: The number of bytes that have been processed and can be discarded from the buffer.
    ///
    /// # Safety
    /// The caller must ensure `data_len` does not exceed the available data length.
    fn advance(self, data_len: usize);
}

/// A guard providing write access to an output buffer with zero-copy semantics.
///
/// This trait enables efficient data transmission by allowing direct mutation
/// of the underlying byte buffer while ensuring proper commit semantics.
pub trait WriteGuard<'a>: Deref<Target = [u8]> + DerefMut {
    /// Commits the written data to the transport layer.
    ///
    /// This operation typically triggers actual transmission of the buffered data.
    /// The guard is consumed to ensure no further modifications occur after commit.
    fn submit(self);
}

/// A communication endpoint supporting bidirectional data transfer.
///
/// This trait abstracts various communication mechanisms (sockets, shared memory, etc.)
/// while providing consistent read/write operations through guard patterns.
pub trait Endpoint {
    /// The error type that may occur during endpoint operations.
    type Error: StdError + Send + Sync + 'static;

    /// The read guard type for this endpoint.
    type ReadGuard<'a>: ReadGuard<'a>
    where
        Self: 'a;

    /// The write guard type for this endpoint.
    type WriteGuard<'a>: WriteGuard<'a>
    where
        Self: 'a;

    /// Acquires a read guard for receiving data.
    ///
    /// # Returns
    /// - `Ok(Self::ReadGuard)`: Successfully obtained a read guard
    /// - `Err(Self::Error)`: Failed to establish read access
    fn read(&mut self) -> Result<Self::ReadGuard<'_>, Self::Error>;

    /// Acquires a write guard for sending data.
    ///
    /// # Parameters
    /// - `data_len`: The expected size of data to be written
    ///
    /// # Returns
    /// - `Ok(Self::WriteGuard)`: Successfully obtained a write guard with at least `data_len` capacity
    /// - `Err(Self::Error)`: Failed to allocate write buffer
    fn write(&mut self, data_len: usize) -> Result<Self::WriteGuard<'_>, Self::Error>;
}

/// A trait for creating communication endpoints.
///
/// This trait abstracts the creation of endpoints for different transport mechanisms,
/// supporting both connectionless and connection-oriented protocols.
pub trait Transport {
    /// The endpoint type created by this transport.
    type Endpoint: Endpoint;

    /// The error type that may occur during transport operations.
    type Error: StdError + Send + Sync + 'static;

    /// Creates a new communication endpoint.
    ///
    /// For connection-oriented protocols, this typically creates a listening endpoint.
    /// For connectionless protocols, this creates a standalone communication object.
    ///
    /// # Returns
    /// - `Ok(Self::Endpoint)`: Successfully created endpoint
    /// - `Err(Self::Error)`: Failed to create endpoint
    fn create(&self) -> Result<Self::Endpoint, Self::Error>;

    /// Establishes a connection to a remote endpoint.
    ///
    /// # Returns
    /// - `Ok(Self::Endpoint)`: Successfully connected endpoint
    /// - `Err(Self::Error)`: Connection failed
    fn connect(&self) -> Result<Self::Endpoint, Self::Error>;
}

mod shmem;
pub use shmem::*;

#[cfg(test)]
mod tests;
